<template>
	<view>
		<scroll-view scroll-x scroll-with-animation :scroll-left="scrollLeft" class="tab">
			<view class="box flex-r">
				<block v-for="(item, index) of tabData" :key="index">
					<view
						:id="`_tab_${index}`"
						class="tab-item"
						:class="{ 'tab-active': activeIndex === index }"
						:style="{
							color: activeIndex === index ? defaultConfig.activeColor : defaultConfig.textColor
						}"
						@tap="handleClick(index, item.status)"
					>
						{{ item.name }}
					</view>
				</block>

				<!-- 滑块 -->
				<view
					class="underline"
					:style="{
						transform: 'translateX(' + slider.left + 'px)',
						width: defaultConfig.underLineWidth + 'px',
						height: defaultConfig.underLineHeight + 'px',
						backgroundColor: defaultConfig.underLineColor
					}"
				></view>
			</view>
		</scroll-view>
	</view>
</template>

<script>
export default {
	name: 'hyl-tabs',
	props: {
		config: {
			type: Object,
			default: () => {
				return {}
			}
		},
		tabData: {
			type: Array,
			default: () => {
				return []
			}
		},
		defaultIndex: {
			type: Number,
			default: 0
		}
	},
	data() {
		return {
			// 内部维护的数据对象，为每个item单独维护一个slider的滑块对象
			tabList: [],
			//当前激活项的index
			activeIndex: -1,
			//滑块
			//1、滑块滚动的时机	-> 点击tab
			//2、滑块滚动的距离
			slider: {
				//滑块的距离
				left: 0
			},
			// scrollView 的横向滚动条位置
			scrollLeft: 0,
			defaultConfig: {
				textColor: '#333',
				activeColor: '#eb3729',
				// 下划线的宽度
				underLineWidth: 24,
				// 下划线的高度
				underLineHeight: 2,
				// 下划线的颜色
				underLineColor: '#eb3729'
			}
		}
	},
	watch: {
		//监听tabData变化
		tabData: {
			//当tabData变化时，回调的方法
			handler(val) {
				this.tabList = val
				// tabList 数据就已经和tabData同步了
				// 维护tabList中的每个item,为DOM渲染完成之后
				// this.$nextTick() uniapp虽然支持，但存在兼容性问题
				setTimeout(() => {
					//计算item的slider
					this.undateTabWidth()
				}, 0)
			},
			//当前的handler回调将会在侦听器开始之后立即被调用
			immediate: true
		},
		//监听激活项变化
		defaultIndex: {
			//当defaultIndex变化时，回调的方法
			handler(val) {
				this.activeIndex = val
			},
			//当前的handler回调将会在侦听器开始之后立即被调用
			immediate: true
		},
		config: {
			handler(val) {
				this.defaultConfig = { ...this.defaultConfig, ...val }
			},
			//当前的handler回调将会在侦听器开始之后立即被调用
			immediate: true
		}
	},
	methods: {
		/* 更新tab的宽度、*/
		undateTabWidth() {
			//tabItem 的宽度,tabItem 的left 为tabList中的每个item维护一个slider对象
			let data = this.tabList
			if (data.length === 0) return false
			//uniapp中拿到渲染之后的dom
			//获取dom固定写法
			const query = uni.createSelectorQuery().in(this)
			//循环数据源
			data.forEach((item, index) => {
				//获取DOM
				query
					.select(`#_tab_${index}`)
					.boundingClientRect(res => {
						//console.log(res)
						//res就是拿到的dom
						item._slider = {
							left: res.left + (res.width - this.defaultConfig.underLineWidth) / 2
						}
						//运算完成后,计算一次滑块位置
						if (data.length - 1 === index) {
							this.tabToIndex()
						}
					})
					.exec()
			})
		},
		handleClick(index, state) {
			this.activeIndex = index
			this.tabToIndex()
			this.$emit('tabClick', state)
		},
		/*根据当前的activeIndex计算滑块滚动位置*/
		tabToIndex() {
			if (this.tabList.length === 0) return
			const aindex = this.activeIndex

			//计算滑块的滚动 === this.slider.left
			this.slider = {
				//tabItem 的宽度,tabItem 的left 、slider的 width
				//left = tabItem.left + (tabItem.width - slider.width) / 2;
				left: this.tabList[aindex]._slider.left
			}
			//控制scrollLeft滚动
			this.scrollLeft = this.activeIndex * this.defaultConfig.underLineWidth
		}
	}
}
</script>

<style lang="stylus" scoped>
.tab
	width 100%
	position relative
	font-size 28rpx
	color #333
.box
	width 100%
	position relative
	.tab-item
		padding 10rpx 30rpx
		height 45px
		line-height 45px
		white-space nowrap
		position relative
	.tab-active
		color #eb3729
		font-weight bold
	.underline
		height 4rpx
		width 48rpx
		background #eb3729
		border-radius 6rpx
		transition 0.5s
		position absolute
		bottom 0
</style>
